package framework.storage;

import org.apache.commons.io.IOUtils;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

public interface FileStorage {

    /**
     * 是否启用
     *
     * @return
     */
    default boolean enable() {
        return true;
    }

    /**
     * 判定路径是否启用了压缩
     *
     * @param filePath
     * @return
     */
    default boolean isCompression(String filePath) {
        String[] starts = this.compressionPathStarts();
        if (starts == null) return false;
        if (starts.length == 0) return false;
        for (String s : starts) {
            if (filePath.startsWith(s)) return true;
        }
        return false;
    }

    /**
     * 加载启用压缩算法的起始路径
     *
     * @return
     */
    default String[] compressionPathStarts() {
        return null;
    }

    /**
     * 存储文件
     *
     * @param content
     * @param filePath
     * @return long save content length
     * @throws IOException
     */
    default long save(String content, String filePath) throws IOException {
        byte[] contentBytes = content.getBytes();
        try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(contentBytes, 0, contentBytes.length)) {
            return this.save(byteArrayInputStream, filePath);
        }
    }

    /**
     * 存储文件
     *
     * @param inputStream
     * @param filePath
     * @return save content length
     * @throws IOException
     */
    default long save(InputStream inputStream, String filePath) throws IOException {
        boolean compression = this.isCompression(filePath);
        return this.save(inputStream, filePath, compression);
    }

    /**
     * 存储文件
     *
     * @param inputStream
     * @param filePath
     * @return save content length
     * @throws IOException
     */
    long save(InputStream inputStream, String filePath, boolean compression) throws IOException;

    /**
     * 将字节数组存储到存储器中
     *
     * @param data
     * @param filePath
     * @return save content length
     * @throws IOException
     */
    default long save(byte[] data, String filePath) throws IOException {
        try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data, 0, data.length)) {
            return this.save(byteArrayInputStream, filePath);
        }
    }

    /**
     * 读取文件
     *
     * @param filePath
     * @return
     */
    default String getString(String filePath) throws IOException {
        String str = null;
        try (InputStream stream = this.getStream(filePath)) {
            str = IOUtils.toString(stream, "UTF-8");
        }
        return str;
    }

    /**
     * 读取字节内容
     *
     * @param filePath
     * @return
     */
    default byte[] getData(String filePath) throws IOException {
        byte[] content;
        try (InputStream stream = this.getStream(filePath)) {
            content = IOUtils.toByteArray(stream);
        }
        return content;
    }

    /**
     * 读取文件
     *
     * @param filePath
     * @return
     */
    default InputStream getStream(String filePath) throws IOException {
        boolean compression = this.isCompression(filePath);
        return this.getStream(filePath, compression);
    }

    /**
     * 读取文件
     *
     * @param filePath
     * @param compression
     * @return
     */
    InputStream getStream(String filePath, boolean compression) throws IOException;

    /**
     * 删除文件
     *
     * @param filePath
     */
    default void delete(String filePath) throws IOException {
        boolean compression = this.isCompression(filePath);
        this.delete(filePath, compression);
    }

    /**
     * 删除文件
     *
     * @param filePath
     */
    void delete(String filePath, boolean compression) throws IOException;

    /**
     * 尝试删除文件
     *
     * @param filePath
     */
    default boolean tryDelete(String filePath, boolean compression) {
        boolean deleted = true;
        try {
            this.delete(filePath, compression);
        } catch (Exception e) {
            deleted = false;
        }
        return deleted;
    }

    default boolean tryDelete(String filePath) {
        boolean compression = this.isCompression(filePath);
        return this.tryDelete(filePath, compression);
    }

}
